<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="nl" lang="nl">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title></title>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<link rel="stylesheet" href="css/style.css" type="text/css" />
</head>
<body>
<div class="document">


<img alt="images/driebit_logo.gif" src="images/driebit_logo.gif" />
<div class="section" id="lypo-technische-documentatie">
<h1><a class="toc-backref" href="#id2">LYPO / Technische documentatie</a></h1>
<p>di 09 jun 2009 14:03:54 CEST- 14:03</p>
<div class="contents topic" id="inhoud">
<p class="topic-title first">Inhoud</p>
<ul class="simple">
<li><a class="reference internal" href="#lypo-technische-documentatie" id="id2">LYPO / Technische documentatie</a><ul>
<li><a class="reference internal" href="#inleiding" id="id3">Inleiding</a></li>
<li><a class="reference internal" href="#terminologie" id="id4">Terminologie</a><ul>
<li><a class="reference internal" href="#container" id="id5">Container</a></li>
</ul>
</li>
<li><a class="reference internal" href="#leesvoer" id="id6">Leesvoer</a></li>
<li><a class="reference internal" href="#oppositeness-berekenen" id="id7">Oppositeness berekenen</a><ul>
<li><a class="reference internal" href="#uitleg-sanne" id="id8">Uitleg Sanne</a></li>
<li><a class="reference internal" href="#toevoeging-sjors" id="id9">Toevoeging Sjors</a></li>
</ul>
</li>
<li><a class="reference internal" href="#content-model" id="id10">Content model</a><ul>
<li><a class="reference internal" href="#lypo-users" id="id11">LYPO Users</a></li>
<li><a class="reference internal" href="#container-users" id="id12">Container Users</a></li>
<li><a class="reference internal" href="#user-profiles" id="id13">User Profiles</a></li>
<li><a class="reference internal" href="#statements" id="id14">Statements</a></li>
<li><a class="reference internal" href="#statement-answers" id="id15">Statement Answers</a></li>
<li><a class="reference internal" href="#comments" id="id16">Comments</a></li>
<li><a class="reference internal" href="#stemmen" id="id17">Stemmen</a></li>
</ul>
</li>
<li><a class="reference internal" href="#opensocial-views" id="id18">OpenSocial Views</a><ul>
<li><a class="reference internal" href="#profile" id="id19">Profile</a><ul>
<li><a class="reference internal" href="#viewer-owner" id="id20">VIEWER = OWNER</a></li>
<li><a class="reference internal" href="#viewer-is-geen-owner-en-heeft-gadget-niet" id="id21">VIEWER is geen OWNER en heeft gadget niet</a></li>
<li><a class="reference internal" href="#viewer-is-geen-owner-en-heeft-gadget-wel" id="id22">VIEWER is geen OWNER en heeft gadget wel</a></li>
</ul>
</li>
<li><a class="reference internal" href="#canvas" id="id23">Canvas</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<p>Zie ook: <a class="reference external" href="api.html">API docs</a></p>
<div class="section" id="inleiding">
<h2><a class="toc-backref" href="#id3">Inleiding</a></h2>
<p>Driebit ontwikkelt een Opensocial Gadget voor CousCous Global, genaamd LYPO (Love Your Perfect Opposite)
Doel van de gadget is het vinden van je &quot;perfect opposite&quot; en daarmee in debat te gaan door het beantwoorden.
De gadget is te plaatsen op container sites die OpenSocial gadgets ondersteunen zoals Hyves, MySpace etc.)</p>
</div>
<div class="section" id="terminologie">
<h2><a class="toc-backref" href="#id4">Terminologie</a></h2>
<div class="section" id="container">
<h3><a class="toc-backref" href="#id5">Container</a></h3>
<p>Een container is niets meer dan een sociale netwerk site (Hyves, Orkut, MySpace etc.) die OpenSocial heeft geimplementeerd.
Het is als het waren de container waarin de gadget zich bevindt en waarmee gegevens worden uitgewisseld middels de OpenSocial API.</p>
</div>
</div>
<div class="section" id="leesvoer">
<h2><a class="toc-backref" href="#id6">Leesvoer</a></h2>
<ul class="simple">
<li><a class="reference external" href="http://wiki.opensocial.org/index.php?title=Containers">Opensocial Wiki Overzicht Containers</a></li>
<li><a class="reference external" href="http://www.slideshare.net/chanezon/google-io-2008-opensocial-meet-the-containers">Google IO 2008 - Opensocial: Meet The Containers</a></li>
</ul>
</div>
<div class="section" id="oppositeness-berekenen">
<h2><a class="toc-backref" href="#id7">Oppositeness berekenen</a></h2>
<p>Een van de lastigte zaken is het berekenen van de mate van &quot;oppositeness&quot; (hoveel procent zijn twee gebuikers opposites van elkaar)</p>
<div class="section" id="uitleg-sanne">
<h3><a class="toc-backref" href="#id8">Uitleg Sanne</a></h3>
<p>Hierbij zoals beloofd mijn voorstel voor een FYPO-algoritme. Het is al
laat en ik weet dus niet of ik het helemaal helder op heb geschreven dus
sta open voor alle vragen en commentaar. Het algoritme bepaald de mate
van oppositeness tussen twee gebruikers en maar geeft nog niet aan hoe
er gezocht moet worden naar &quot;opposite gebruikers&quot; om deze calculatie te
gaan uitvoeren. Bij een niet al te groot gebruikers bestand is het nog
mogelijk iedereen te vergelijken met elkaar maar dat gaat veranderen als
er veel mensen mee gaan doen. Een keuze-algoritme / zoek-algoritme dat
uitgaat van een selectie voor de berekening gedaan wordt van oppositeness
is een volgende stap. Als je denkt dat dit al nodig is laat het me weten dan denk ik er over na.</p>
<p><strong>Aannames:</strong></p>
<p>1. De gebruiker geeft in elk geval antwoord op 20 vragen met
&quot;eens&quot;/&quot;oneens&quot;/&quot;geen antwoord&quot; de antwoorden op deze vragen worden
gezien als de VALUES van de gebruiker</p>
<p>2. &quot;geen antwoord&quot; kan gezien wordt als waardevrij, dat wil zeggen dat
de mate van &quot;oppositeness&quot; NIET kleiner wordt wanneer twee gebruikers
&quot;geen antwoord&quot; op dezelfde vraag hebben geantwoord.</p>
<p><strong>Representatie van VALUES en OPPOSITENESS.</strong></p>
<p>Deze reeks antwoorden is te zien als een bit string met een minimale
lengte van 20 met op positie 1 de representatie van antwoord 1 en op
positie 20 die van antwoord 20 enzovoort. Naarmate de gebruiker meer
vragen heeft beantwoord wordt de bit string langer. De bit string is er
een waarbij iedere positie in de string drie verschillende waarden aan
kan nemen 0, 1, of NULL (0 = oneens, 1 = eens, NULL = geen antwoord)</p>
<p>De mate van OPPOSITENESS is het aantal antwoorden dat de gebruikers
verschillend hebben wordt gerepresenteerd in een bitstring</p>
<p><strong>Berekening aan de hand van een voorbeeld:</strong></p>
<p>De VALUES van gebruiker Jan die vraag 1 en 2 niet heeft beantwoord,
verder op alle vragen &quot;eens&quot; heeft geantwoord behalve op vraag 20 wordt
gerepresenteerd met bit string NULL1111111111111111110</p>
<p>Gebruiker Piet, die het alleen eens was met vraag 3, 5 en 17 krijgt bit
string 00100010000000001000 voor zijn/haar VALUES</p>
<p>De mate van oppositeness wordt als volgt berekend:</p>
<pre class="literal-block">
positie.x(jan) - positie.x(piet) = positie.x(OPPOSITENESS,jan,piet)

positie.1(VALUES, jan) = NULL
positie.1(VALUES, piet) = 0
positie.1(OPPOSITENESS,jan,piet) = 0

positie.17(VALUES, jan) = 1
positie.17(VALUES, piet) = 1
positie.17(OPPOSITENESS,jan,piet) = 0

positie.20(VALUES, jan) = 0
positie.20(VALUES, piet) = 0
positie.20(OPPOSITENESS,jan,piet) = 0
</pre>
<p>De representatie van de OPPOSITENESS van Jan en Piet is dus de volgende
bit string:</p>
<pre class="literal-block">
01011101111111110110
</pre>
<p>De mate van oppositeness kan omgezet worden in een percentage op de
volgende manier:</p>
<pre class="literal-block">
Voor x = 1 TO LENGTH_of_bitstring(OPPOSITENESS,jan,piet) DO

      Oppositecount = Oppositecount + positie.x(OPPOSITENESS,jan,piet)


OPPOSITENESS% = OPPOSITECOUNT / LENGTH_of_bitstring *100

in dit geval is de OPPOSITECOUNT 15 en de LENGTH_of_bitstring 20

OPPOSITENESS% = 75%
</pre>
<p>Wanneer de bit string van gebruiker X langer wordt omdat deze meer
vragen heeft beantwoord kan deze nog steeds met gebruiker Y vergeleken
worden die minder vragen heeft beantwoord.
Er wordt namelijk bij de berekening van de oppositeness uitgegaan van de
lengte van de grootste VALUES bit string voor het bepalen van de lengte
van de OPPOSITENESS bitstring, de niet ingevulde posities in de VALUES
bit string van gebruiker Y worden beschouwd als NULL voor de berekening
van de OPPOSITENESS bit string. Op die manier worden mensen die een
ongelijk aantal vragen hebben beantwoord minder snel als opposites
aangemerkt. Hier zou ook een andere keuze gemaakt kunnen worden waarbij
alleen die vragen bekeken worden die door zowel gebruiker X als Y zijn
ingevuld maar dat haalt de incentive weg om meer vragen te beantwoorden.
Op deze manier zullen de wat meer gevorderde gebruikers elkaar vaker als
opposite gaan treffen en de beginners ook elkaar. Dit is denk ik een
interessante dynamiek voor de gebruiker.</p>
<p>---</p>
<p>Meteen nog een kleine toevoeging voor de duidelijkheid:</p>
<pre class="literal-block">
positie.x(VALUES, gebruikerA) = NULL
positie.x(VALUES, gebruikerB) = 1
positie.x(OPPOSITENESS,gebruikerA,gebruikerB) = 0
</pre>
<p>Dit geeft dus aan dat als gebruiker A &quot;geen antwoord&quot; heeft ingevuld en gebruiker B &quot;eens&quot; de waarde van de OPPOSITENESS voor de betreffende positie (net als in het geval dat gebruikerB &quot;oneens&quot; zou invullen) 0 wordt.</p>
<p>Laat me weten als er iets niet klopt of onduidelijk is.</p>
<p>Hartelijke groeten,</p>
<p>Sanne</p>
</div>
<div class="section" id="toevoeging-sjors">
<h3><a class="toc-backref" href="#id9">Toevoeging Sjors</a></h3>
<p>Zoals ik het lees komt het er op neer dat er geteld word hoeveel
antwoorden (eens/oneens) twee mensen verschillen. &quot;Geen mening&quot; maakt
het dat voor die vraag de 2 mensen niet verschillen
Dat deel je door het aantal maximale aantal &quot;echte antwoorden&quot; (Piet
heeft ze alle 20 beantwoordt) en dan weer maal 100 en dan heb je het
percentage.</p>
<p>Voorbeeldje:</p>
<pre class="literal-block">
Vraag | Jan         | Piet        | Resultaat
------+-------------+-------------+-----------
1     | geen mening | oneens      | geen verschil
2     | eens        | oneens      | verschil
3     | eens        | eens        | geen verschil
4     | eens        | oneens      | verschil
5     | eens        | eens        | geen verschil
6     | eens        | oneens      | verschil
7     | eens        | oneens      | verschil
8     | eens        | oneens      | verschil
9     | eens        | oneens      | verschil
10    | eens        | oneens      | verschil
11    | eens        | oneens      | verschil
12    | eens        | oneens      | verschil
13    | eens        | oneens      | verschil
14    | eens        | oneens      | verschil
15    | eens        | oneens      | verschil
16    | eens        | oneens      | verschil
17    | eens        | eens        | geen verschil
18    | eens        | oneens      | verschil
19    | eens        | oneens      | verschil
20    | oneens      | oneens      | geen verschil
</pre>
<p>De uitslag zou hier dan dus zijn:
vragen met verschil (15) / maximale aantal antwoorden (20) * 100</p>
<p>Jan en Piet hebben een opposite ratio van 75%</p>
<pre class="literal-block">
Ook als Piet er een paar had beantwoord met geen mening is het aantal
&quot;echte antwoorden&quot; 20 in mijn opzet. Het is namelijk zo dat er wel 20
vragen behandeld zijn door de gebruiker al is een deel met &quot;geen mening&quot;
beantwoord.
</pre>
</div>
</div>
<div class="section" id="content-model">
<h2><a class="toc-backref" href="#id10">Content model</a></h2>
<p>LYPO bestaat grofweg uit gebruikers, gebruikers-profielen, stellingen, antwoorden op stellingen, reacties en stemmen op reacties.
Omdat de LYPO widget op verschillende &quot;containers&quot; geplaatst kan worden (in eerste insantie alleen op Hyves) is het zaak om de juiste gegevens van de gebruiker te &quot;cachen&quot; in een database.
Daarom zal er per gebruike en per container een profiel worden opgeslagen met gegevens over de gebruierk van dat die specifieke container.</p>
<p>Bij de eerste aanmelding wordt er een algemene LYPO gebruiker gemaakt die we later kunnen gebruiken om alle installaties van de gadget op andere containers samen te kunnen voegen.
Deze gebruiker dient als koppeling tussen alle specifieke container gebruikers (Hyves, Orkut, etc)</p>
<div class="section" id="lypo-users">
<h3><a class="toc-backref" href="#id11">LYPO Users</a></h3>
</div>
<div class="section" id="container-users">
<h3><a class="toc-backref" href="#id12">Container Users</a></h3>
</div>
<div class="section" id="user-profiles">
<h3><a class="toc-backref" href="#id13">User Profiles</a></h3>
</div>
<div class="section" id="statements">
<h3><a class="toc-backref" href="#id14">Statements</a></h3>
</div>
<div class="section" id="statement-answers">
<h3><a class="toc-backref" href="#id15">Statement Answers</a></h3>
</div>
<div class="section" id="comments">
<h3><a class="toc-backref" href="#id16">Comments</a></h3>
</div>
<div class="section" id="stemmen">
<h3><a class="toc-backref" href="#id17">Stemmen</a></h3>
</div>
</div>
<div class="section" id="opensocial-views">
<h2><a class="toc-backref" href="#id18">OpenSocial Views</a></h2>
<p>Er zijn verschillende views die de LYPO gadget gaat odnersteunen.
De gadget gedraagt zich afhankelijk van de rol en eigenschappen van kijker naar de gadget op verschillende manieren.
Hieronder wordt uitgelegd wat de functionaliteiten per OpenSocial view en per situatie zijn.</p>
<div class="section" id="profile">
<h3><a class="toc-backref" href="#id19">Profile</a></h3>
<p>Dit is de view die je ziet op een profiel pagina, en staat bij Hyves bijvoorbeeld in de rechterkolom.</p>
<div class="section" id="viewer-owner">
<h4><a class="toc-backref" href="#id20">VIEWER = OWNER</a></h4>
<p>De bekijke van het profiel is ook de eigenaar</p>
</div>
<div class="section" id="viewer-is-geen-owner-en-heeft-gadget-niet">
<h4><a class="toc-backref" href="#id21">VIEWER is geen OWNER en heeft gadget niet</a></h4>
<p>De bekijker van het profiel is een bezoeker en heeft de gadget niet geinstalleerd.</p>
</div>
<div class="section" id="viewer-is-geen-owner-en-heeft-gadget-wel">
<h4><a class="toc-backref" href="#id22">VIEWER is geen OWNER en heeft gadget wel</a></h4>
<p>De bekijker van het profiel is een bezoeker en heeft de gadget ook.</p>
</div>
</div>
<div class="section" id="canvas">
<h3><a class="toc-backref" href="#id23">Canvas</a></h3>
<p>Dit is de grotere (detail / extended) view waarin nagenoeg alle handelingen plaatsvinden.</p>
<p><a class="reference external" href="mailto:hidde&#64;driebit.nl">Hidde Braun</a></p>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Version:</th><td class="field-body">1.0</td>
</tr>
<tr class="field"><th class="field-name">Author:</th><td class="field-body"><a class="reference external" href="mailto:hidde&#64;driebit.nl">Hidde Braun</a></td>
</tr>
<tr class="field"><th class="field-name">Author:</th><td class="field-body"><a class="reference external" href="mailto:sjors&#64;driebit.nl">Sjors Rijsdam</a></td>
</tr>
<tr class="field"><th class="field-name">Company:</th><td class="field-body"><a class="reference external" href="http://www.driebit.nl">Driebit</a></td>
</tr>
<tr class="field"><th class="field-name">Date:</th><td class="field-body">di 09 jun 2009 14:03:54 CEST</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</body>
</html>
